{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'20180801': 9.8, '20180802': 11.2, '20180803': 16, '20180804': 18, '20180805': 14.6}\n"
     ]
    }
   ],
   "source": [
    "#高阶函数练习\n",
    "#常见的高阶函数: map() filter() reduce()\n",
    "price_array=[9.8,11.2,16,18,14.6]\n",
    "date_base=20180801\n",
    "date_array = [str(date_base + ind) for ind, _ in enumerate(price_array)]\n",
    "\n",
    "stock_dict = {date:price for date, price in zip(date_array, price_array)}\n",
    "print(stock_dict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(9.8, 11.2), (11.2, 16), (16, 18), (18, 14.6)]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pp_array = [(price1,price2) for price1, price2 in zip(price_array[:-1], price_array[1:])]\n",
    "pp_array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(9.8, 11.2), (11.2, 16), (16, 18), (18, 14.6)]\n",
      "[0, 0.143, 0.429, 0.125, -0.189]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from functools import reduce\n",
    "print(pp_array)\n",
    "\n",
    "def change(a,b):\n",
    "    return round((b-a)/a,3)\n",
    "\n",
    "change_array =list(map(lambda pp: reduce(change,pp), pp_array))\n",
    "\n",
    "change_array.insert(0,0)\n",
    "\n",
    "print(change_array)\n",
    "\n",
    "def ff(f):\n",
    "    return list(map(lambda pp: reduce(f,pp), pp_array))\n",
    "\n",
    "def add(a,b):\n",
    "    return a+b\n",
    "\n",
    "f = lambda a,b:a+b\n",
    "ff(f)\n",
    "add(1,2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(123, 'Google', 'Runoob', 'Taobao')\n"
     ]
    }
   ],
   "source": [
    "aTuple = (123, 'Google', 'Runoob', 'Taobao')\n",
    "list1 = list(aTuple)\n",
    "print (aTuple)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['20180801', '20180802', '20180803', '20180804', '20180805']\n",
      "[9.8, 11.2, 16, 18, 14.6]\n",
      "[0, 0.143, 0.429, 0.125, -0.189]\n",
      "<class '__main__.stock'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "OrderedDict([('20180801', stock(date='20180801', price=9.8, change=0)),\n",
       "             ('20180802', stock(date='20180802', price=11.2, change=0.143)),\n",
       "             ('20180803', stock(date='20180803', price=16, change=0.429)),\n",
       "             ('20180804', stock(date='20180804', price=18, change=0.125)),\n",
       "             ('20180805', stock(date='20180805', price=14.6, change=-0.189))])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from collections import namedtuple\n",
    "from collections import OrderedDict\n",
    "print(date_array)\n",
    "print(price_array)\n",
    "print(change_array)\n",
    "stock_namedtuple = namedtuple('stock', ('date','price','change'))\n",
    "stock_dict = OrderedDict((date,stock_namedtuple(date,price,change))for date,price,change in zip(date_array, price_array, change_array ) )\n",
    "#stock_dict = OrderedDict(stock_namedtuple(date,price,change) for date,price,change in zip(date_array, price_array, change_array))\n",
    "print(stock_namedtuple)\n",
    "stock_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[stock(date='20180802', price=11.2, change=0.143),\n",
       " stock(date='20180803', price=16, change=0.429),\n",
       " stock(date='20180804', price=18, change=0.125)]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "up_days = filter(lambda day: day.change > 0, stock_dict.values())\n",
    "list(up_days)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "odict_keys(['20180801', '20180802', '20180803', '20180804', '20180805'])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stock_dict.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "所有上涨的交易日： [stock(date='20180802', price=11.2, change=0.143), stock(date='20180803', price=16, change=0.429), stock(date='20180804', price=18, change=0.125)]\n",
      "计算所有上涨的总和： 0.697\n",
      "所有下跌的交易日: [stock(date='20180805', price=14.6, change=-0.189)]\n",
      "计算所有上涨的总和： -0.189\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "stock_array_dict must be OrderedDict",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-10-34a9ff29714a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     27\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'计算所有上涨的总和：'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mfilter_stock\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstock_dict\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mwant_up\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mwant_calc_sum\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     28\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 29\u001b[1;33m \u001b[0mfilter_stock\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'price_array'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     30\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-10-34a9ff29714a>\u001b[0m in \u001b[0;36mfilter_stock\u001b[1;34m(stock_array_dict, want_up, want_calc_sum)\u001b[0m\n\u001b[0;32m      2\u001b[0m     \u001b[1;31m#如果输入参数不是有序字典,提示错误\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m     \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstock_array_dict\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mOrderedDict\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m         \u001b[1;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'stock_array_dict must be OrderedDict'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      6\u001b[0m     \u001b[1;31m#三目表达式   条件为真时的结果 if 判段的条件 else 条件为假时的结果\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTypeError\u001b[0m: stock_array_dict must be OrderedDict"
     ]
    }
   ],
   "source": [
    "def filter_stock(stock_array_dict, want_up=True, want_calc_sum= False):\n",
    "    #如果输入参数不是有序字典,提示错误\n",
    "    if not isinstance(stock_array_dict, OrderedDict):\n",
    "        raise TypeError('stock_array_dict must be OrderedDict')\n",
    "    \n",
    "    #三目表达式   条件为真时的结果 if 判段的条件 else 条件为假时的结果   \n",
    "    filter_func = (lambda stock: stock.change> 0) if want_up else(lambda stock: stock.change < 0)\n",
    "    \n",
    "    want_days = filter(filter_func, stock_array_dict.values())\n",
    "    \n",
    "    if not  want_calc_sum:\n",
    "        return want_days\n",
    "    \n",
    "    #计算涨跌幅之和\n",
    "    change_sum = 0.0\n",
    "    for day in want_days:\n",
    "        change_sum +=day.change\n",
    "    return change_sum     \n",
    "\n",
    "#example1 = list(filter_stock(stock_dict))\n",
    "print('所有上涨的交易日：',list(filter_stock(stock_dict)))\n",
    "\n",
    "print('计算所有上涨的总和：',filter_stock(stock_dict,want_up=True,want_calc_sum=True))\n",
    "      \n",
    "print('所有下跌的交易日:',list(filter_stock(stock_dict,want_up=False)))\n",
    "     \n",
    "print('计算所有上涨的总和：',filter_stock(stock_dict,want_up=False,want_calc_sum=True))\n",
    "#试错，输入字符串，输出TypeError\n",
    "filter_stock('price_array')\n",
    "      "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[stock(date='20180802', price=11.2, change=0.143), stock(date='20180803', price=16, change=0.429), stock(date='20180804', price=18, change=0.125)]\n",
      "[stock(date='20180805', price=14.6, change=-0.189)]\n",
      "0.697\n",
      "-0.189\n"
     ]
    }
   ],
   "source": [
    "#偏函数，\n",
    "from functools import partial\n",
    "\n",
    "filter_stock_up_days = partial(filter_stock, want_up = True, want_calc_sum = False)\n",
    "\n",
    "filter_stock_down_days = partial(filter_stock, want_up = False, want_calc_sum = False)\n",
    "\n",
    "filter_stock_up_sums = partial(filter_stock, want_up = True, want_calc_sum = True)\n",
    "\n",
    "filter_stock_down_sums = partial(filter_stock, want_up = False, want_calc_sum = True)\n",
    "\n",
    "\n",
    "print(list(filter_stock_up_days(stock_dict)))\n",
    "print(list(filter_stock_down_days(stock_dict)))\n",
    "print(filter_stock_up_sums(stock_dict))\n",
    "print(filter_stock_down_sums(stock_dict))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
